import uuid
from datetime import datetime
from typing import Optional, List
from fastapi import APIRouter, Depends, Query, Body, HTTPException, status, UploadFile, File, Form, Header
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from sqlalchemy.ext.asyncio import AsyncSession

from module_speech.service.speech_service import SpeechService
from module_speech.service.speech_client_service import ClientUserService
from module_speech.service.speech_quota_service import QuotaService
from module_speech.entity.vo.speech_vo import (
    SpeechRecognizeRequest, SpeechRecognizeResponse,
    SpeechModelInfo, SpeechQuotaInfo
)
from utils.response_util import ResponseUtil
from utils.page_util import PageResponseModel
from config.get_db import get_db
from utils.log_util import logger
from utils.speech_auth_util import SpeechAuthUtil


router = APIRouter(prefix="/api/v1/speech", tags=["语音识别-对外API"])
security = HTTPBearer()


async def get_client_user_from_api_key(
    authorization: HTTPAuthorizationCredentials = Depends(security),
    db: AsyncSession = Depends(get_db)
):
    """
    通过API Key获取客户端用户信息
    """
    try:
        # 从Authorization header中提取API Key
        api_key = authorization.credentials
        
        # 验证API Key并获取用户信息
        client_user = await SpeechAuthUtil.verify_api_key(db, api_key)
        if not client_user:
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail="无效的API Key"
            )
        
        return client_user
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"API Key认证失败: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="认证失败"
        )


@router.post("/recognize")
async def recognize_audio(
    file: UploadFile = File(..., description="音频文件"),
    model_name: str = Form("sensevoice-small", description="识别模型"),
    language: str = Form("auto", description="语言代码"),
    callback_url: Optional[str] = Form(None, description="回调地址"),
    client_ip: str = Depends(SpeechAuthUtil.get_client_ip),
    db: AsyncSession = Depends(get_db),
    client_user = Depends(get_client_user_from_api_key)
):
    """
    语音识别接口
    """
    try:
        # 检查用户状态
        if client_user.status != 1:
            return ResponseUtil.error(message="账户已禁用", code=403)
        
        # 验证IP白名单
        if not await ClientUserService.verify_ip_whitelist(client_user, client_ip):
            return ResponseUtil.error(message="IP地址不在白名单中", code=403)
        
        # 检查模型权限
        if model_name not in client_user.allowed_models:
            return ResponseUtil.error(message="无权限使用该模型", code=403)
        
        # 检查功能权限
        if not client_user.allowed_features.get('upload', False):
            return ResponseUtil.error(message="无上传识别权限", code=403)
        
        # 生成请求ID
        api_request_id = str(uuid.uuid4())
        
        # 预估音频时长用于配额检查（简单估算）
        file_size_mb = len(await file.read()) / (1024 * 1024)
        estimated_duration = file_size_mb * 0.5  # 粗略估算，实际需要根据音频格式计算
        await file.seek(0)  # 重置文件指针
        
        # 检查配额
        quota_check = await QuotaService.check_quota_available(
            db, client_user.client_user_id, estimated_duration
        )
        if not quota_check['available']:
            return ResponseUtil.error(
                message=quota_check.get('message', '配额不足'),
                code=429,
                data={'quota_info': quota_check}
            )
        
        # 构建识别请求
        request_data = SpeechRecognizeRequest(
            model_name=model_name,
            language=language,
            callback_url=callback_url,
            api_key=client_user.api_key,
            api_request_id=api_request_id
        )
        
        # 执行语音识别
        result = await SpeechService.upload_and_recognize_audio(
            db=db,
            file=file,
            request_data=request_data,
            client_user=client_user,
            user_type='client'
        )
        
        # 构建响应
        response_data = {
            'api_request_id': api_request_id,
            'record_id': result.get('record_id'),
            'status': result.get('status', 'processing'),
            'result': result.get('result'),
            'message': result.get('message', '识别成功'),
            'quota_remaining': quota_check.get('quota_remaining', 0)
        }
        
        return ResponseUtil.success(data=response_data, message="识别请求提交成功")
        
    except Exception as e:
        logger.error(f"语音识别失败: {str(e)}")
        return ResponseUtil.error(message=f"语音识别失败: {str(e)}")


@router.get("/models")
async def get_available_models(
    db: AsyncSession = Depends(get_db),
    client_user = Depends(get_client_user_from_api_key)
):
    """
    获取可用的识别模型列表
    """
    try:
        # 获取所有可用模型
        all_models = await SpeechService.get_available_models()
        
        # 过滤用户有权限的模型
        available_models = []
        for model in all_models:
            if model['name'] in client_user.allowed_models:
                available_models.append(model)
        
        return ResponseUtil.success(data=available_models, message="获取模型列表成功")
        
    except Exception as e:
        logger.error(f"获取模型列表失败: {str(e)}")
        return ResponseUtil.error(message=f"获取模型列表失败: {str(e)}")


@router.get("/quota")
async def get_quota_info(
    db: AsyncSession = Depends(get_db),
    client_user = Depends(get_client_user_from_api_key)
):
    """
    获取配额信息
    """
    try:
        # 获取配额详情
        quota_details = await QuotaService.get_quota_usage_details(
            db, client_user.client_user_id
        )
        
        # 构建响应数据
        quota_info = {
            'user_id': client_user.client_user_id,
            'plan_type': client_user.plan_type,
            'quota_monthly': quota_details['quota_info']['monthly_quota'],
            'quota_used': quota_details['quota_info']['used_quota'],
            'quota_remaining': quota_details['quota_info']['remaining_quota'],
            'usage_rate': quota_details['quota_info']['usage_rate'],
            'reset_date': quota_details['quota_info']['reset_date'],
            'rate_limit_per_minute': quota_details['rate_limiting']['requests_per_minute'],
            'current_month_requests': quota_details['usage_stats']['monthly_requests'],
            'today_requests': quota_details['usage_stats']['today_requests']
        }
        
        return ResponseUtil.success(data=quota_info, message="获取配额信息成功")
        
    except Exception as e:
        logger.error(f"获取配额信息失败: {str(e)}")
        return ResponseUtil.error(message=f"获取配额信息失败: {str(e)}")


@router.get("/records/{api_request_id}")
async def get_recognition_result(
    api_request_id: str,
    db: AsyncSession = Depends(get_db),
    client_user = Depends(get_client_user_from_api_key)
):
    """
    根据API请求ID获取识别结果
    """
    try:
        # 获取识别记录
        record = await SpeechService.get_speech_record_by_api_request_id(
            db, api_request_id, client_user.client_user_id
        )
        
        if not record:
            return ResponseUtil.error(message="识别记录不存在", code=404)
        
        # 构建结果数据
        result_data = {
            'api_request_id': record.api_request_id,
            'record_id': record.record_id,
            'status': record.status,
            'model_name': record.model_name,
            'language': record.language,
            'audio_duration': float(record.audio_duration or 0),
            'recognized_text': record.recognized_text,
            'confidence_score': float(record.confidence_score or 0),
            'create_time': record.create_time.isoformat() if record.create_time else None,
            'complete_time': record.update_time.isoformat() if record.update_time else None,
            'error_message': record.error_message if record.status == 'failed' else None
        }
        
        return ResponseUtil.success(data=result_data, message="获取识别结果成功")
        
    except Exception as e:
        logger.error(f"获取识别结果失败: {str(e)}")
        return ResponseUtil.error(message=f"获取识别结果失败: {str(e)}")


@router.get("/records")
async def get_recognition_history(
    status: Optional[str] = Query(None, description="状态过滤"),
    start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD)"),
    end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD)"),
    page_num: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页数量"),
    db: AsyncSession = Depends(get_db),
    client_user = Depends(get_client_user_from_api_key)
):
    """
    获取识别历史记录
    """
    try:
        # 构建查询参数
        from module_speech.entity.vo.speech_vo import SpeechQueryModel
        from datetime import datetime
        
        query_params = SpeechQueryModel(
            client_user_id=client_user.client_user_id,
            user_type='client',
            status=status,
            start_date=datetime.strptime(start_date, '%Y-%m-%d').date() if start_date else None,
            end_date=datetime.strptime(end_date, '%Y-%m-%d').date() if end_date else None,
            page_num=page_num,
            page_size=page_size
        )
        
        # 获取记录列表
        result = await SpeechService.get_speech_records(db, query_params)
        
        return ResponseUtil.success(data=result, message="获取识别历史成功")
        
    except Exception as e:
        logger.error(f"获取识别历史失败: {str(e)}")
        return ResponseUtil.error(message=f"获取识别历史失败: {str(e)}")


@router.get("/usage/statistics")
async def get_usage_statistics(
    period: str = Query("month", description="统计周期: day/week/month"),
    start_date: Optional[str] = Query(None, description="开始日期 (YYYY-MM-DD)"),
    end_date: Optional[str] = Query(None, description="结束日期 (YYYY-MM-DD)"),
    db: AsyncSession = Depends(get_db),
    client_user = Depends(get_client_user_from_api_key)
):
    """
    获取使用统计
    """
    try:
        from module_speech.service.speech_usage_service import ClientUsageService
        from datetime import datetime, date
        
        # 设置默认日期范围
        if not start_date:
            if period == 'day':
                start_date = date.today().isoformat()
            elif period == 'week':
                start_date = (date.today() - timedelta(days=7)).isoformat()
            else:  # month
                start_date = (date.today() - timedelta(days=30)).isoformat()
        
        if not end_date:
            end_date = date.today().isoformat()
        
        # 转换日期
        start_date_obj = datetime.strptime(start_date, '%Y-%m-%d').date()
        end_date_obj = datetime.strptime(end_date, '%Y-%m-%d').date()
        
        # 获取使用趋势
        trend_data = await ClientUsageService.get_usage_trend(
            db, client_user.client_user_id, start_date_obj, end_date_obj, period
        )
        
        # 获取月度汇总
        current_date = date.today()
        monthly_summary = await ClientUsageService.get_monthly_usage_summary(
            db, client_user.client_user_id, current_date.year, current_date.month
        )
        
        result_data = {
            'trend_data': [item.dict() for item in trend_data],
            'monthly_summary': monthly_summary.dict() if monthly_summary else None,
            'period': period,
            'date_range': {
                'start_date': start_date,
                'end_date': end_date
            }
        }
        
        return ResponseUtil.success(data=result_data, message="获取使用统计成功")
        
    except Exception as e:
        logger.error(f"获取使用统计失败: {str(e)}")
        return ResponseUtil.error(message=f"获取使用统计失败: {str(e)}")


@router.get("/health")
async def health_check():
    """
    健康检查接口
    """
    return ResponseUtil.success(
        data={
            'status': 'healthy',
            'timestamp': datetime.now().isoformat(),
            'version': '1.0.0'
        },
        message="服务正常"
    )


@router.get("/rate-limit")
async def check_rate_limit(
    db: AsyncSession = Depends(get_db),
    client_user = Depends(get_client_user_from_api_key)
):
    """
    检查速率限制状态
    """
    try:
        from module_speech.service.speech_usage_service import ClientUsageService
        
        # 获取当前小时的请求数
        current_hour_requests = await ClientUsageService._get_current_hour_requests(
            db, client_user.client_user_id
        )
        
        # 计算剩余请求数
        remaining_requests = max(0, client_user.rate_limit_per_minute * 60 - current_hour_requests)
        
        rate_limit_info = {
            'rate_limit_per_minute': client_user.rate_limit_per_minute,
            'rate_limit_per_hour': client_user.rate_limit_per_minute * 60,
            'current_hour_requests': current_hour_requests,
            'remaining_requests': remaining_requests,
            'reset_time': datetime.now().replace(minute=0, second=0, microsecond=0).isoformat()
        }
        
        return ResponseUtil.success(data=rate_limit_info, message="获取速率限制信息成功")
        
    except Exception as e:
        logger.error(f"获取速率限制信息失败: {str(e)}")
        return ResponseUtil.error(message=f"获取速率限制信息失败: {str(e)}")

# 将router对象赋值给speechApiController变量，以便在__init__.py中导入
speechApiController = router 